package com.wuliang.generate.common.core.basic;

import io.micrometer.core.lang.NonNullApi;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.data.repository.NoRepositoryBean;

import javax.persistence.EntityManager;
import javax.validation.constraints.NotNull;
import java.util.Optional;

/**
 * 自定义Repository的实现类，此类不应该被Spring扫描
 *
 * @param <T> 实体类对象，应作为事务性操作的实体类对象
 * @author 邬魉
 */
@NoRepositoryBean
@NonNullApi
public class BaseRepositoryImpl<T extends BasicEntity> extends SimpleJpaRepository<T, Integer> implements BaseRepository<T> {

    /**
     * 对SimpleJpaRepository的构造函数进行重写
     *
     * @param entityInformation 实体类对象的相关信息
     * @param entityManager     实体类对象的管理
     */
    public BaseRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
        super(entityInformation, entityManager);
    }

    /**
     * @param domainClass
     * @param em
     */
    public BaseRepositoryImpl(Class<T> domainClass, EntityManager em) {
        super(domainClass, em);
    }

    /**
     * 根据数据状态进行分页查询的具体实现
     *
     * @param dataStatus 数据状态
     * @param pageable   分页对象
     * @return 分页后的数据
     */
    @Override
    public Page<T> findPageByDataStatus(Integer dataStatus, Pageable pageable) {
        return this.findAll((Specification<T>) (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder
                .equal(root.get("dateStatus"), dataStatus), pageable);
    }

    /**
     * 根据主键检索数据，
     * 注意此方法，检索子对象也是检索的主键，
     * 所以  如果你子对象的关联字段为 非主键，那么请调用 findOne 方法
     *
     * @param id 主键
     * @return 实体类数据
     */
    @Override
    public Optional<T> findById(@NotNull Integer id) {
        // 首先调用原有的方法来查询数据
        Optional<T> entityOptional = super.findById(id);
        // 如果查询到的数据不为空，但数据状态为删除状态。
        if (entityOptional.isPresent() && entityOptional.get().getDataStatus() != 0) {
            // 则返回查询结果为空
            return Optional.empty();
        }
        // 否则正常返回
        return entityOptional;
    }
}
